package at.jku.pervasive.simulator;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import at.jku.pervasive.Position;

public abstract class UbisenseServerSimulator extends Thread
{

	private List<UbisenseServerSimulatorThread> threads;
	ServerSocket serverSocket;
	private final int port;
	private boolean running;

	public UbisenseServerSimulator(final int port)
	{
		super();
		this.running = true;
		this.port = port;
		this.threads = new ArrayList<UbisenseServerSimulatorThread>(1);

		Runnable listenForConnections = new Runnable()
		{
			public void run()
			{
				try
				{
					serverSocket = new ServerSocket(port);

					while (true)
					{
						Socket client = serverSocket.accept();
						UbisenseServerSimulatorThread t = getThread(client);
						t.start();
						threads.add(t);
					}
				} catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		};
		new Thread(listenForConnections).start();
	}

	@Override
	public void run()
	{
		while (running)
		{
			Position nextPosition = getNextPosition();
			for (UbisenseServerSimulatorThread thread : threads)
			{
				if (!thread.isAlive())
					threads.remove(thread);
				else
					thread.getPositionBuffer().setPosition(nextPosition);
			}

			try
			{
				Thread.sleep(getWaitingTime());
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}

	protected long getWaitingTime()
	{
		return 500;
	}

	public void setRunning(boolean running)
	{
		this.running = running;
	}

	protected UbisenseServerSimulatorThread getThread(Socket socket)
	{
		return new UbisenseServerSimulatorThread(new PositionBuffer(), socket);
	}

	protected abstract Position getNextPosition();

}
